<template>
  <el-select
    :value="label"
    ref="elSelect"
    popper-class="OceInputTree"
    :placeholder="placeholder"
    :size="size"
  >
    <div class="box">
      <el-input
        v-model="key"
        @input="keyChange"
        size="mini"
        class="search"
        placeholder="请输入关键字（支持拼音）"
      ></el-input>
      <el-option ref="elOption" :value="dic" class="option">
        <oce-giant-tree
          :nodes="dic"
          :setting="setting"
          @onCreated="onCreated"
          @onClick="selectNode"
        />
      </el-option>
    </div>
  </el-select>
</template>

<script>
import PinyinMatch from '../../../../assets/pinyin-match'

const defaultProps = {
  label: 'label',
  value: 'id',
  parentId: 'parentId',
  children: 'children',
}

export default {
  name: 'OceInputTree',
  props: {
    dic: {
      type: Array,
      // default: [],
    },
    props: {
      type: Object,
      default: () => defaultProps,
    },
    multiple: {
      type: Boolean,
      default() {
        return false
      },
    },
    value: {
      // eslint-disable-next-line
      type: String | Array,
    },
    addDiyDom: {
      type: Function,
    },
    placeholder: {
      type: String,
    },
    size: {
      type: String,
    },
  },
  data() {
    return {
      label: '', // 下拉框内的值
      inputValue: '', // 选中的值
      ztreeObj: null,
      key: '',
      valCreate: false,
    }
  },
  components: {},
  watch: {
    inputValue: {
      handler() {
        if (this.valCreate) this.setVal()
      },
      deep: true,
    },
    value: {
      handler(val) {
        if (val != this.inputValue) this.inputValue = this.$ocean.deepClone(val)
        this.$nextTick(() => {
          this.label = this.getSelectLabel(val)
        })
      },
      deep: true,
    },
  },
  computed: {
    setting() {
      const setting = {
        // callback: {
        //   // beforeClick: this.ztreeClickCallback,
        // },
        check: {
          enable: this.multiple,
        },
        data: {
          simpleData: {
            enable: true,
            pIdKey: this.props.parentId || 'parentId',
            idKey: this.props.value || 'id',
            // children: this.props.children,
          },
          key: {
            name: this.props.label || 'label',
          },
        },
        view: {
          showIcon: true,
          addDiyDom: this.addDiyDom,
          fontCss: (id, node) => {
            if (node.disabled) {
              return { color: '#C4C4CC', cursor: 'no-drop' }
            }
            return {}
          },
        },
      }
      return setting
    },
    treeProps() {
      // eslint-disable-next-line prefer-object-spread
      return Object.assign({}, defaultProps, this.props)
    },
  },
  methods: {
    getSelectLabel(val) {
      if (!this.ztreeObj) return null
      let node = this.ztreeObj.getNodeByParam(this.treeProps.value, val)
      if (!node) {
        this.dic.forEach((item) => {
          if (item[this.treeProps.value] == val) node = item
        })
      }
      // console.log(this.treeProps.value, val, node)
      return node[this.treeProps.label]
    },
    // eslint-disable-next-line no-unused-vars
    ztreeClickCallback(treeId, treeNode) {
      if (treeNode.disabled) return false
      return true
    },
    // 选中节点
    // eslint-disable-next-line no-unused-vars
    selectNode(event, treeId, treeNode, clickFiag) {
      if (!this.multiple) {
        // 单选模式
        // this.label = treeNode[this.props.label || 'label']
        this.inputValue = treeNode[this.props.value || 'id']
        this.$refs.elSelect.handleClose()
      }
    },
    // ztree实例化完成
    onCreated(ztreeObj) {
      // console.log(ztreeObj)
      this.ztreeObj = ztreeObj
      this.ztreeObj.setting.callback.beforeClick = this.ztreeClickCallback
      ztreeObj.expandNode(ztreeObj.getNodes()[0], true)
      this.$emit('onCreated', ztreeObj)
    },
    // 关闭el-select组件默认点击关闭事件
    handleOptionClick() {
      this.$refs.elSelect.handleOptionSelect = function (option, byClick) {
        if (this.multiple) {
          const value = (this.value || []).slice()
          const optionIndex = this.getValueIndex(value, option.value)
          if (optionIndex > -1) {
            value.splice(optionIndex, 1)
          } else if (
            this.multipleLimit <= 0 ||
            value.length < this.multipleLimit
          ) {
            value.push(option.value)
          }
          this.$emit('input', value)
          this.emitChange(value)
          if (option.created) {
            this.query = ''
            this.handleQueryChange('')
            this.inputLength = 20
          }
          if (this.filterable) this.$refs.input.focus()
        } else {
          this.$emit('input', option.value)
          this.emitChange(option.value)
          // this.visible = false
        }
        this.isSilentBlur = byClick
        this.setSoftFocus()
        if (this.visible) return
        this.$nextTick(() => {
          this.scrollToOption(option)
        })
      }
      this.$refs.elSelect.$off('handleOptionClick')
      this.$refs.elSelect.$on(
        'handleOptionClick',
        this.$refs.elSelect.handleOptionSelect
      )
    },
    // 动态搜索
    keyChange(val) {
      this.fuzzySearch(val)
    },
    scanHide() {
      this.key = ''
      const nodes = this.ztreeObj.transformToArray(this.ztreeObj.getNodes())
      // console.log(nodes[0])
      nodes.forEach((item) => {
        // console.log(item)
        if (item.hide) {
          this.ztreeObj.hideNode(item)
        } else {
          this.ztreeObj.showNode(item)
        }
      })
    },
    // 模糊搜索树
    fuzzySearch(key) {
      const fuzzySearchFlag = new Date().getTime()
      const nodes = this.ztreeObj.transformToArray(this.ztreeObj.getNodes())
      if (!key) {
        // this.ztreeObj.expandAll(false)
        // this.ztreeObj.showNodes(nodes)
        this.scanHide()
        return
      }
      let isShow
      let path
      const temp = nodes.splice(0, 1)
      nodes.push(temp[0])
      nodes.forEach((item) => {
        if (!item.fuzzySearchFlag || item.fuzzySearchFlag !== fuzzySearchFlag) {
          // eslint-disable-next-line no-param-reassign
          item.fuzzySearchFlag = fuzzySearchFlag
          isShow =
            Boolean(
              // eslint-disable-next-line comma-dangle
              PinyinMatch.match(item[this.props.label || 'label'], key)
            ) && !item.hide
          if (isShow) {
            path = item.getPath()
            path.forEach((el) => {
              // eslint-disable-next-line no-param-reassign
              el.fuzzySearchFlag = fuzzySearchFlag
            })
            this.ztreeObj.showNodes(path)
          } else {
            this.ztreeObj.hideNode(item)
          }
        }
      })
      this.ztreeObj.expandAll(true)
    },
    setVal() {
      /**
       * v-mode
       * @property {Object}
       */
      this.$emit('input', this.inputValue)
      /**
       * v-mode
       * @property {Object}
       */
      this.$emit('change', this.inputValue)
    },
  },
  created() {
    // this.$nextTick(() => {
    // console.log(this.value, this.dic)
    this.inputValue = this.$ocean.deepClone(this.value)
    this.setVal()
    this.valCreate = true
    // })
  },
  mounted() {
    this.handleOptionClick()
  },
}
</script>

<style scoped lang="scss"></style>
<style lang="scss">
.OceInputTree {
  .el-select-dropdown__wrap {
    padding: 0 6px;
  }
  .ztree li a {
    width: calc(100% - 28px);
    &:hover {
      background: #f5f7fa;
    }
  }
  .el-select-dropdown__item.hover {
    background: #fff;
  }

  .box {
    height: 250px;
    .search {
      height: 30px;
    }

    .option {
      height: calc(100% - 30px) !important;
      overflow: auto;
    }
  }
}
</style>
